using System;
using System.Collections.Generic;
using System.Text;

using System.Windows.Forms;
using System.Drawing;

using System.Xml;

namespace ClientGUI
{

    /// <summary>
    /// This class represents a text element in an xml tree.
    /// It is immediately taken out of this tree and its contents get
    /// turned into a TextDraw.
    /// </summary>
	class TextModule:Module, ITextAble, IWordAble
	{
		String my_text;
		Word [] my_words;
		public TextModule(XmlNode text, Module parent,
			DisplayDocument host, TagConfig tagconfig)
            :base(text, parent, host, tagconfig)
		{
            this.my_name = text.Name;
			my_text = text.Value;
			String [] strings = text.Value.Split(' ', '\t', '\n', '\r');

			my_words = new Word[strings.Length];
			for (int i = 0; i < strings.Length; ++i ) {
				my_words[i] = new Word(strings[i]);
			}
		}

		public String Text { get { return my_text + " "; } }
		public bool Pure { get { return true; } }

		private String[] getlines(float ch_width, int width)
		{
			String[] paras = my_text.Split('\n');
			if (paras == null) {
				paras = new String[1];
				paras[0] = my_text;
			}
			List<String> lines = new List<string>();

			foreach (String para in paras) {
				if (para.Length > 1) {
					String[] words = para.Split(' ');
					if (words == null) {
						lines.Add(para);
						continue;
					}
					StringBuilder line = new StringBuilder();
					int line_w = 0;
					for (int i = 0; i < words.Length; ++i) {
						if (line_w + words[i].Length * ch_width < width) {
							line_w += (int)(((float)words[i].Length) * ch_width);
							line.Append(words[i]);
							if (line_w + 1 == width) {
								lines.Add(line.ToString());
								line = new StringBuilder();
								line_w = 0;
							} else {
								line_w += 1;
								line.Append(" ");
							}
						} else if (line_w == 0) {
							return null;
						} else {
							lines.Add(line.ToString());
							line = new StringBuilder();
							line_w = 0;
						}
					}
					if (line.Length > 0)
						lines.Add(line.ToString());
				}
			}

			return lines.ToArray();
		}

		/*public override void Draw(Graphics g, int x, int y, int w, int h)
		{
			Font f = new Font("Sans Serif", 12.0f);
			float char_width = f.Size;
			String[] lines = getlines(char_width, w);
			if (lines != null) {
				float height = f.GetHeight();
				foreach (String line in lines) {
					g.DrawString(line, f, Brushes.Black, new PointF(x, y));
					y = (int)(((float)y) + height);
				}
			}
			base.Draw(g, x, y, w, h);
			my_X = x;
			my_Y = y;
		} PROBABLY NEVER USED*/
		public override void Space(int w)
		{ //shouldn't ever get called
            my_width = w;
            int x = 0;
            int y = 0;
            int max_font_height = 0;
            for (int i = 0; i < Length; ++i)
            {
                if (x + this[i].Width > Width)
                {
                    x = 0;
                    y += max_font_height;
                }
                x += ((int)this[i].Width) + 3;
                max_font_height += Math.Max(max_font_height, (int)this[i].Height);
            }
            my_height = y + max_font_height;

/*            int y = 0;
			Font f = new Font("Sans Serif", 12.0f);
			float char_width = f.Size;
			String[] lines = getlines(char_width, x);
			if (lines == null) {
				y = -1;
				return;
			}
			float height = f.GetHeight();
			
			height += 1.0f;
			y = ((int)(height)) * lines.Length;
			base.Space(x);*/
		}

        public override XmlNode GetDocument(XmlDocument doc)
        {
            return doc.CreateTextNode(my_text);
        }
		#region IWordAble Members

		public Word this[int index]
		{
			get
			{
				return my_words[index];
			}
		}

		public int Length
		{
			get
			{
				return my_words.Length;
			}
		}

		#endregion

        public override ClientGUI.Modules.Drawing.DisplayArea GetDisplayArea()
        {
            return new Modules.Drawing.BlankDisplayArea();
        }
    }
}
